package com.emcom.gotour.utils;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.util.WebUtils;

import com.emcom.gotour.enums.PagingAction;

/**
 * Paging Data Utils.<br/>
 * Paging's objectList must be setted.<br/>
 * Paging's pageSize must be setted.<br/>
 * @author Cui Zuoli
 * @version 1.0
 */
public class PagingUtils {

	private static Log logger = LogFactory.getLog(PagingUtils.class);

	public final static String PAGING_SESSION = "_PAGING";

	public final static int PAGE_SIZE = 10;

	public static void savePaging(HttpServletRequest request, Paging paging, String pagingName) {
		WebUtils.setSessionAttribute(request, pagingName.concat(PagingUtils.PAGING_SESSION), paging);
	}

	public static Paging loadPaging(HttpServletRequest request, String pagingName) {
		return (Paging)WebUtils.getSessionAttribute(request, pagingName.concat(PagingUtils.PAGING_SESSION));
	}

	public static void initPaging(HttpServletRequest request, List<?> objectList, int pageSize, String pagingName) {
		Paging paging = loadPaging(request, pagingName);
		if(paging == null || paging.getObjectList() == null) {
			forceInitPaging(request, objectList, pageSize, pagingName);
		}
	}

	public static Paging paging(PagingAction pagingAction, Paging paging, int page) {
		if(PagingAction.FIRST.compareTo(pagingAction) == 0) {
			return firstPage(paging);
		}
		if(PagingAction.LAST.compareTo(pagingAction) == 0) {
			return lastPage(paging);
		}
		if(PagingAction.PREVIOUS.compareTo(pagingAction) == 0) {
			return previousPage(paging);
		}
		if(PagingAction.NEXT.compareTo(pagingAction) == 0) {
			return nextPage(paging);
		}
		if(PagingAction.TO.compareTo(pagingAction) == 0) {
			return customPage(paging, page);
		}
		return firstPage(paging);
	}

	public static void forceInitPaging(HttpServletRequest request, List<?> objectList, int pageSize, String pagingName) {
		Paging paging = new Paging();
		paging.setCurrentPage(1);
		paging.setPageSize(pageSize);
		paging.setObjectList(objectList);
		savePaging(request, paging, pagingName);
	}

	public static Paging customPage(Paging paging, int page) {
		// the value must be setting value.<br/>
		List<?> objectList = paging.getObjectList();
		int pageSize = paging.getPageSize();
		// --
		int currentPage;
		int allPage;
		int resultSize;
		int prePage;
		int nextPage;
		int firstPage;
		int lastPage;
		// result size.<br/>
		if(objectList == null || objectList.size() == 0) {
			currentPage = 1;
			allPage = 1;
			resultSize = 0;
			prePage = 1;
			nextPage = 1;
			firstPage = 1;
			lastPage = 1;
		} else {
			resultSize = objectList.size();
			// all page size.<br/>
			allPage = resultSize / pageSize;
			if(resultSize % pageSize > 0) {
				allPage++;
			}
			// current page.<br/>
			if(page < 1) {
				currentPage = 1;
			} else if(page > allPage) {
				currentPage = allPage;
			} else {
				currentPage = page;
			}
			// previous page.<br/>
			prePage = currentPage - 1;
			if(prePage < 1) {
				prePage = 1;
			}
			// next page.<br/>
			nextPage = currentPage + 1;
			if(nextPage > allPage) {
				nextPage = allPage;
			}
			// first page & last page.<br/>
			firstPage = 1;
			lastPage = allPage;
		}
		// the list for paging result.
		List<Object> resultList = new ArrayList<Object>();
		// compute paging start number and end number.<br/>
		int start = (currentPage - 1) * pageSize;
		int end = start + pageSize;
		if(end > resultSize) {
			end = resultSize;
		}
		for(int i = start; i < end; i++) {
			resultList.add(objectList.get(i));
		}
		// return result object.<br/>
		paging.setCurrentPage(currentPage);
		paging.setAllPage(allPage);
		paging.setResultSize(resultSize);
		paging.setPrePage(prePage);
		paging.setNextPage(nextPage);
		paging.setFirstPage(firstPage);
		paging.setLastPage(lastPage);
		paging.setPagingList(resultList);
		if(logger.isDebugEnabled()) {
			logger.debug(paging);
		}
		return paging;
	}

	public static Paging firstPage(Paging paging) {
		return customPage(paging, 1);
	}

	public static Paging lastPage(Paging paging) {
		int pageSize = paging.getPageSize();
		List<?> objectList = paging.getObjectList();
		int page;
		if(objectList == null || objectList.size() == 0) {
			page = 1;
		} else {
			int resultSize = objectList.size();
			int allPage = resultSize / pageSize;
			if(resultSize % pageSize > 0) {
				allPage++;
			}
			page = allPage;
		}
		return customPage(paging, page);
	}

	public static Paging nextPage(Paging paging) {
		int page = paging.getCurrentPage();
		return customPage(paging, ++page);
	}

	public static Paging previousPage(Paging paging) {
		int page = paging.getCurrentPage();
		return customPage(paging, --page);
	}

}
